<?php

declare (strict_types=1);

namespace app\admin\model\admin;

use app\common\model\admin\RoleMenu as RoleMenuModel;
use Exception;
use think\Collection;

/**
 * 后台用户角色与菜单权限关系模型
 * Class RoleMenu
 */
class RoleMenu extends RoleMenuModel
{
    /**
     * 新增关系记录
     * @param int $roleId
     * @param array $menuIds
     * @return array|bool|Collection
     * @throws Exception
     */
    public static function increased(int $roleId, array $menuIds): Collection|bool|array
    {
        $data = [];
        foreach ($menuIds as $menuId) {
            $data[] = [
                'role_id' => $roleId,
                'menu_id' => $menuId,
                'create_time' => time(),
            ];
        } 
        return (new static)->saveAll($data);
    }

    /**
     * 更新关系记录
     * @param int $roleId
     * @param array $newMenus
     * @return array|bool|Collection
     * @throws Exception
     */
    public static function updates(int $roleId, array $newMenus): Collection|bool|array
    {
        // 已分配的权限集
        $assignMenuIds = self::getMenuIds([$roleId]);
        /**
         * 找出删除的权限
         * 假如已有的权限集合是A，界面传递过得权限集合是B
         * 权限集合A当中的某个权限不在权限集合B当中，就应该删除
         * 使用 array_diff() 计算补集
         */
        if ($deleteMenuIds = array_diff($assignMenuIds, $newMenus)) {
            self::deleteAll([
                ['role_id', '=', $roleId],
                ['menu_id', 'in', $deleteMenuIds]
            ]);
        }
        /**
         * 找出添加的权限
         * 假如已有的权限集合是A，界面传递过得权限集合是B
         * 权限集合B当中的某个权限不在权限集合A当中，就应该添加
         * 使用 array_diff() 计算补集
         */
        $newMenuIds = array_diff($newMenus, $assignMenuIds);
        $data = [];
        foreach ($newMenuIds as $menuId) {
            $data[] = [
                'role_id' => $roleId,
                'menu_id' => $menuId,
            ];
        }
        return (new static)->saveAll($data);
    }

    /**
     * 获取指定角色的所有菜单id
     * @param array $roleIds 角色ID集
     * @return array
     */
    public static function getMenuIds(array $roleIds): array
    {
        return (new self)->where('role_id', 'in', $roleIds)->column('menu_id');
    }

    /**
     * 批量删除
     * @param array $where
     * @return false||int
     * @throws DbException
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     */
    public static function setDeleteAll(array $where=[])
    {
        return (new static)->where($where)->where(['is_delete' => 0])->update(['is_delete' => 1]);
    }
}
